package com.econ.powercloud.ems.service.biz;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.econ.powercloud.common.base.facade.enums.StatusType;
import com.econ.powercloud.common.base.facade.exception.CommonRuntimeException;
import com.econ.powercloud.common.base.facade.pojo.PageResult;
import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.ems.constant.SysConstant;
import com.econ.powercloud.ems.dal.entity.EmsSyncIotProduct;
import com.econ.powercloud.ems.pojo.ProductVO;
import com.econ.powercloud.ems.pojo.scene.OpenApiSceneProductVO;
import com.econ.powercloud.ems.service.dao.EmsSyncIotProductDAO;
import com.econ.powercloud.ems.service.biz.scene.SceneBizService;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author : zjf
 * @Description : 产品配置service
 * @Date : 2022/5/27 9:09
 * @Modified by : zjf
 */
@Service
public class ProductConfigureService {

    @Autowired
    private EmsSyncIotProductDAO emsSyncIotProductDAO;
    @Autowired
    private SynchronousSceneDataService synchronousSceneDataService;
    @Autowired
    private SceneBizService sceneBizService;

    /**
     * 获取产品配置列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    public PageResult<List<ProductVO>> getList(String search, Integer pageNo, Integer pageSize){
        Page<EmsSyncIotProduct> pageResult = emsSyncIotProductDAO.selectByPage(search,pageNo, pageSize);
        if (pageResult.getRecords().size() > 0) {
            List<ProductVO> productVOS = JacksonUtil.convertToList(pageResult.getRecords(), ProductVO.class);
            return PageResult.<List<ProductVO>>builder().data(productVOS).pageNo(pageNo).totalCount((int) pageResult.getTotal()).build();
        }
        return PageResult.<List<ProductVO>>builder().data(Collections.EMPTY_LIST).pageNo(pageNo).totalCount((int) pageResult.getTotal()).build();
    }

    /**
     * 同步产品列表
     * 逻辑是 会新增未同步的产品信息(之前有的产品不管修改时间是否是最新的都不做处理)
     */
    @Transactional(rollbackFor = Exception.class)
    public void syncProductList(){
        List<EmsSyncIotProduct> productSyncList = emsSyncIotProductDAO.list();
        List<String> productKeys = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(productSyncList)){
            productKeys.addAll(productSyncList.stream().map(EmsSyncIotProduct::getProductKey).collect(Collectors.toList()));
        }
        //查询场景服务中的属于EMS应用方向的产品有哪些
        List<OpenApiSceneProductVO> sceneProductList = sceneBizService.getSceneProduct(null, SysConstant.EMS_APPLICATION);
        if(CollectionUtils.isEmpty(sceneProductList)){
            throw new CommonRuntimeException(StatusType.FAIL, "获取产品基本信息数据为空！");
        }
        //判断哪些产品是新增的产品,同步这些新增的产品
        List<OpenApiSceneProductVO> newProductVOS = sceneProductList.stream().filter(d-> !productKeys.contains(d.getProductKey())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(newProductVOS)){
            return;
        }
        //开始同步产品信息
        synchronousSceneDataService.initProductAndModuleInfo(newProductVOS);
        //开始同步遥测遥信遥控遥调的信息
        synchronousSceneDataService.initProductYcYxInfo(newProductVOS.stream().map(OpenApiSceneProductVO::getProductKey).collect(Collectors.toList()));
    }

    /**
     * 更新产品信息
     */
    public void updateAllProduct(){
        List<EmsSyncIotProduct> productSyncList = emsSyncIotProductDAO.list();
        this.updateProductPublish(productSyncList);
    }

    /**
     * 更新某个产品信息
     */
    public void updateProductByProductKey(String productKey){
        EmsSyncIotProduct emsSyncIotProduct = emsSyncIotProductDAO.getById(productKey);
        this.updateProductPublish(Lists.newArrayList(emsSyncIotProduct));
    }

    /**
     * 更新产品信息公共方法
     * @param productSyncList : 需要更新的产品信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateProductPublish(List<EmsSyncIotProduct> productSyncList){
        if(CollectionUtils.isEmpty(productSyncList)){
            return;
        }
        Map<String, EmsSyncIotProduct> productSyncMap = productSyncList.stream().collect(Collectors.toMap(EmsSyncIotProduct::getProductKey, d->d,(p1, p2)->p1));
        //查询场景服务中的属于EMS应用方向的产品有哪些
        List<OpenApiSceneProductVO> sceneProductVOList = sceneBizService.getSceneProduct(Lists.newArrayList(productSyncMap.keySet()), SysConstant.EMS_APPLICATION);
        if(CollectionUtils.isEmpty(sceneProductVOList)){
            throw new CommonRuntimeException(StatusType.FAIL, "获取产品基本信息数据为空！");
        }
        //如果同步时间早于修改时间，进行同步，这里只针对从场景中获取到的产品来进行判断
        List<OpenApiSceneProductVO> updateProductVOS = Lists.newArrayList();
        sceneProductVOList.stream().forEach(d->{
            EmsSyncIotProduct emsSyncIotProduct = productSyncMap.get(d.getProductKey());
            if(emsSyncIotProduct.getIotGmtModify() < d.getGmtModify()){
                updateProductVOS.add(d);
            }
        });
        if(CollectionUtils.isEmpty(updateProductVOS)){
            return;
        }
        //开始同步产品与四遥的基本信息
        synchronousSceneDataService.initProductAndModuleInfo(updateProductVOS);
        //开始同步遥测遥信遥控遥调的信息
        synchronousSceneDataService.initProductYcYxInfo(updateProductVOS.stream().map(OpenApiSceneProductVO::getProductKey).collect(Collectors.toList()));
    }

}
